{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loadDataSet(filename):\n",
    "    '''\n",
    "    加载数据\n",
    "    '''\n",
    "    dataList =[]\n",
    "    labelList = []\n",
    "    with open(filename) as f:\n",
    "        for line in f:\n",
    "            lineArr = line.strip().split()\n",
    "            dataList.append([1.0, float(lineArr[0]), float(lineArr[1])])\n",
    "            labelList.append(int(lineArr[2]))\n",
    "    return dataList, labelList"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    '''\n",
    "    sigmoid函数\n",
    "    '''\n",
    "    return 1.0/(1 + np.exp(-z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradAscent(dataMatIn, classLabels, alpha = 0.001, MaxIter = 500):\n",
    "    '''\n",
    "    批处理梯度上升\n",
    "    Args:\n",
    "        dataMatIn: 训练集特征 \n",
    "        classLabels：训练集分类标记\n",
    "        alpha = 0.001：学习率\n",
    "        MaxIter = 500：最大迭代次数\n",
    "    Return:\n",
    "        weights: 更新后的回归系数\n",
    "    '''\n",
    "    dataMatrix = np.mat(dataMatIn)\n",
    "    labelMat = np.mat(classLabels).T\n",
    "    m, n = np.shape(dataMatrix)\n",
    "    weights = np.ones((n,1))\n",
    "    for k in range(MaxIter):\n",
    "        h = sigmoid(dataMatrix * weights)\n",
    "        error = labelMat - h\n",
    "        weights = weights + alpha * dataMatrix.T * error\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[ 4.12414349],\n",
       "        [ 0.48007329],\n",
       "        [-0.6168482 ]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataList, labelList = loadDataSet('data/testSet.txt')\n",
    "weights = gradAscent(dataList, labelList)\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plotBestFit(weights, dataList, labelList):\n",
    "    dataArr = np.array(dataList) \n",
    "    n = np.shape(dataArr)[0]\n",
    "    xcord1 = []\n",
    "    ycord1 = []\n",
    "    xcord2 = []\n",
    "    ycord2 = []\n",
    "    for i in range(n):\n",
    "        if int(labelList[i]) == 1:\n",
    "            xcord1.append(dataArr[i,1])\n",
    "            ycord1.append(dataArr[i,2])\n",
    "        else:\n",
    "            xcord2.append(dataArr[i,1])\n",
    "            ycord2.append(dataArr[i,2])\n",
    "    fig = plt.figure()\n",
    "    ax = fig.add_subplot(111)\n",
    "    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')\n",
    "    ax.scatter(xcord2, ycord2, s=30, c='green')\n",
    "    x = np.arange(-3.0, 3.0, 0.1).reshape(-1,1)\n",
    "    # 最佳拟合直线: w0+w1*x1+w2*x2=0 —> x2 = (-w0-w1*x1)/w2\n",
    "    # 注意！！！x * (weights[1])顺序不能颠倒\n",
    "    y = (-weights[0]-x * (weights[1]))/weights[2]\n",
    "    ax.plot(x,y)\n",
    "    plt.xlabel('x1')\n",
    "    plt.ylabel('x2')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1f7a1f46278>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotBestFit(weights, dataList, labelList)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stocGradAscent0(dataList, labelList, alpha=0.01):\n",
    "    '''\n",
    "    随机梯度上升\n",
    "    Args:\n",
    "        dataMatrix: 训练集特征 \n",
    "        classLabels：训练集分类标记\n",
    "        alpha = 0.01：学习率\n",
    "    Return:\n",
    "        weights: 更新后的回归系数\n",
    "    '''\n",
    "    dataMatrix = np.mat(dataList)\n",
    "    classLabels = np.mat(labelList).T\n",
    "    m,n = np.shape(dataMatrix)\n",
    "    weights = np.ones((n,1))\n",
    "    for i in range(m):\n",
    "        h = sigmoid(np.sum(dataMatrix[i]*weights))\n",
    "        error = classLabels[i] - h\n",
    "        weights = weights + dataMatrix[i].T * alpha * error \n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[ 1.01702007],\n",
       "        [ 0.85914348],\n",
       "        [-0.36579921]])"
      ]
     },
     "execution_count": 169,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataList, labelList = loadDataSet('data/testSet.txt')\n",
    "weights = stocGradAscent0(dataList, labelList)\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEKCAYAAAAFJbKyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzt3Xl8VPW5+PHPk4WwhbCFPQGEEKQICDGoFBWVRWrd6r5bK+J1a6vS7ba9197+fiWIimIFXIpVtNpF67VKABVBRTYFUSEQ1kDYkRAIJJnkuX9koCFkmUlm5pwz87xfr7zInDkz80zmcJ453+e7iKpijDHGBCrO6QCMMcZ4iyUOY4wxQbHEYYwxJiiWOIwxxgTFEocxxpigWOIwxhgTFEscxhhjgmKJwxhjTFAscRhjjAlKgtMBhEPHjh21V69eTodhjDGesXLlyn2qmhrIvlGZOHr16sWKFSucDsMYYzxDRLYGuq81VRljjAmKJQ5jjDFBscRhjDEmKJY4jDHGBCXsiUNEXhSRPSLyVbVt/yUiO0Rklf9nfB2PHScieSKSLyI/D3esxhhjGhaJK47ZwLhatj+hqkP8P+/WvFNE4oFngEuAAcANIjIgrJEaY4xpUNgTh6ouAg404qHZQL6qblLVMuAvwOUhDc4YY0zQnKxx3CciX/qbstrVcn93oKDa7e3+bbUSkQkiskJEVuzduzfUsRrjOQVFBdz/7v1kP5fN/e/eT0FRQcMPMiYATiWOZ4E+wBBgJzC1ln2klm11LpCuqrNUNUtVs1JTAxr8aEzUKigqYPCMwcxcOZPlhcuZuXImg2cMtuRhQsKRxKGqu1W1QlUrgeeoapaqaTuQVu12D6AwEvEZ43U5n+RwuOww5ZXlAJRXlnO47DA5n+Q4HJmJBo4kDhHpWu3mlcBXtey2HMgQkd4i0gy4Hng7EvEZ43VLdyw9kTSOK68sZ9mOZQ5FZKJJJLrjvgYsATJFZLuI3AnkiMgaEfkSGAX8xL9vNxF5F0BVfcB9QC6wFnhDVb8Od7zGRIPh3YeTGJd40rbEuESyu9d2cW9McES1zrKBZ2VlZalNcmhi2fEax/HmqsS4RFo3a83qiatJS0lr+AlMzBGRlaqaFci+NnLcmCiUlpLG6omruXvY3WR3y+buYXdb0jAhE5XTqhsTLQqKCsj5JIelO5YyvPtwJo2YFPDJPy0ljafHPx3mCE0sssRhjEvVbG5atWsVc9bMsSsH4zhrqjLGpaxLrXEru+IwxkWqN01tPbjVtV1qm9KEZrzPEocxLlGzaSqulgYBN3SptSY0Y01VxrhEzaapSioBEP/sO8e71E4aMcmxGMGa0IxdcRjjGrWN9gZIbZVKr5ReZHfPdkWTkI1KN5Y4jHGJ4d2Hs2rXqpNOyolxiVw74FpXdautK06nm9BM5FhTlTEuMWnEJFo3a31iqhC3NE3V5JU4TfhY4jDGJbwy2jsScdpaIu5mc1UZY1zF5tlyhs1VZYzxLOu15X6WOIwxrmK9ttzPEocxxlVsLRH3s8RhjKmVUwXqcPbasqJ7aIS9OC4iLwKXAntUdaB/2xTg+0AZsBG4Q1UP1vLYLUAxUAH4Ai3cWHHcmKZxukB9fC6sxdsWU6mVxEkcI9NHNmkApNPvye3cVhyfDYyrsW0+MFBVBwHrgV/U8/hRqjok0DdkjGk6pwvUaSlpTBoxiW1F21i3bx2rd69m5sqZDJ4xuNFXCU6/p2gS9sShqouAAzW2zfOvKQ7wGdAj3HEYE6sa0zzjhgJ1qE/0bnhP0cINNY4fAu/VcZ8C80RkpYhMiGBMxkSFpduXkvF0BtOXT2d54XJmrJgR0Ld2NxSoQ32id8N7ihaOJg4R+RXgA+bUscsIVR0KXALcKyLn1fNcE0RkhYis2Lt3bxiiNcZbCooKOH/2+ZRWlJ7Y5lMfxaXFDX5rd8O0IqE+0bvhPUULxxKHiNxGVdH8Jq2jQq+qhf5/9wBvAnUeMao6S1WzVDUrNTU1HCGbMLMeL6GV80nOSUnjOJ/6GvzW7obpT0J9onfDe4oWEZlyRER6Ae9U61U1DngcOF9Va708EJFWQJyqFvt/nw88qqpzG3o961XlPdbjJfSyn8tmeeHyWu+7bdBtJCclu34Fv+O9q5btWOaaaeWjVTC9qsI+rbqIvAZcAHQUke3Ab6nqRZUEzBcRgM9UdaKIdAOeV9XxQGfgTf/9CcCrgSQN4031FULdNKW4lwzvPpwvdn2Br9J30vZmcc14K+8tSspLXL+CX1pKmn3+LhSJXlU3qGpXVU1U1R6q+oKq9lXVNH832yGqOtG/b6E/aaCqm1R1sP/nO6r6+3DHapzjtR4vXmhWmzRiEsnNkkmI+/f3w6T4JC7LvOxE0gDrlmqC54ZeVcZ4qsfL8Wa1mStnsrxweZPHF4TL8Tb9icMmkt0tm/vOuo8N929ga9FWTyVp4z62AqBxhUkjJjFnzZxTahxu7PHipWa12pp63LSC3/EaxvFay82DbuaVL19xfe0l1tl6HMY1IlUILSgq4Ncf/Jr38t8DgUv6XsLvRv0u4Neqq+ic3S2bpXctDXW4IeeWjgg140iQBCq0gvi4eHyVPusgEWGuKo4bE6hIFEILigo449kzKCotOrHtpdUv8da6t1hzz5qATlBu+sbeGMebsJzurVTzys3nn0zieDHfzVdysc5qHCYqBFqszvkkh0Olh07ZHsiguOOiYSDZ8SS99K6lPD3+aUe+0dfWIaImq724k11xGM+r2eRRX/fSpTuWopzaPFtJZcAnKLd8Y/e62q7cavLSlVwssSsO43nBTIY3vPtwBDllexxxQZ2g3PCN3etqXrklSAKCnOg+7MUruVhhicN4XjBjQCaNmESbpDanbE9OSj5xgnLzGI2mxuam91ZzCpCJWRNZcueSE92HbUoQ97JeVcbz7n/3fmaunHlKsfruYXfXWlStr1eVW3oc1aapsdXWiyk+Lp7+Hfs3eZEk431uW8jJmLAKtlidlpLG7Ctns/uR3ex+eDezr5h94oTp5sV+mhpbbb2YSitKQ7JIkoktljiM54Vy1tNwTH0SquahpsZWXy8mNyVI437Wq8pEhVCNAQn1GI1genyFO7aGejE1lIRqjvK2pq3YZVccxtNCXewN9RiNUDZ9NTW2mo+vqb4k5JX5uUxkWOIwnhWOk1moF/tpSvNSzaQINCm26u9tcOfBJMUnBdz11c21HxN51lRlPCtckw3W1+wVbHPNgNQBrCxcSSWVJ7YF0rxUXxNXqN5bMHODeW3aexNeljiMZ0X6ZBZsvaKgqIC31r11UtIAaJnYssHmpUjMwBtMXcjr83MdZ3Wa0LCmKuNZkV7DI9jmmpxPcigpLzlpmyBckXlFgycrt33Dj4b5uaxOEzoRSRwi8qKI7BGRr6ptay8i80Vkg//fdnU89jb/PhtE5LZIxGu8IdIns2BP5rXtryhr961t8LXctrBVqGs/TrA6TehE6opjNjCuxrafA++ragbwvv/2SUSkPVVrlA8HsoHf1pVgTOyJ9Mks2JN5U07+bvyG7/X5udx2FedlEUkcqroIOFBj8+XAS/7fXwKuqOWhY4H5qnpAVb8F5nNqAjIxLJIns2BP5k05+UcqKbpp7qpwc9tVnJdFbK4qEekFvKOqA/23D6pq22r3f6uq7Wo85mGguar+j//2r4GjqvpYfa9lc1WZcAl2lcJIrGrY2IKvm+flCodYe7/BCmauKrcnjkeApBqJo0RVp9by/BOACQDp6enDtm7dGq63YoxrNOVkGOzkkNEgUssTe5FXJjncLSJdAfz/7qlln+1A9U+1B1BY25Op6ixVzVLVrNTU1JAHa+oXS00eblJXwfd7r36vwc+irjb/N755I2KfXyDHTSiPLa/XadzCySuOKcB+Vf2DiPwcaK+qk2o8pj2wEhjq3/Q5MExVa9ZLTmJNVZFlTQDOyX4um+WFy+u8v77PorYrDqjqMty2eduwf36BHDd2bNVNVRE5dVGyxnLdFYeIvAYsATJFZLuI3An8ARgtIhuA0f7biEiWiDwP4E8QvwOW+38ebShpmMizbo7Oqa3gW119n8Xx4n1cjdOAohH5/AI5buzYOtWa7UXc8sJS3vlyp2MxRGTkuKreUMddF9Wy7wrgR9Vuvwi8GKbQTAhYN0fnTBoxiTlr5px0cq2pts/ieFt/WkoaR31HOeY71uBjQi2Q42bRtkV2bPlt2nuYqfPX868vd9KuZSJXDOnuWCw25YhpsmiZjsKLjnfbPV7wPeo7ytq9a/Gp78Q+NT+Lms0/Na84antMODR03BQUFZC3L++UxyVIQkwdW7uKjjHt/Q28saKApIQ4HriwLz867zTaNK/7SjPcbOlY02R1tUO/d9N7vPLlK56dF8gN8xoFG0MgNYH6ahuKRqyO0FCs9797PzNWzsBX6TvpcUnxSWy4f4OnjqXGOFhSxrMLNzL70y1UqnLT8J7cO6ovqclJYXk9V3bHjSRLHJFXs5vjzYNu5pI5l3i2qOmGomxjY2ioy2ldBfVOrTrRK6VXRLup1hdrXXEO7jyYVRNXhT02p5SU+fjTJ1uY8dFGDpf6uPLM7vzk4n6ktW8Z1tcNJnFYU5UJiZozrd7/7v1hn901nCIxO224Ymho1tu6moiuHXBtxD+b+mKtK86R6SMjFV5ElfkqeX35Nqa9n8++w6VcfHpnHhmbSWaXZKdDO4XNjmvCwusFczfEH64Y3DgPVm28EmdTVVYqb32xg4sf/4hf//NrTuvYir/fcw7P35blyqQBljhMmHh9XiA3xB9oDMEOkPPKTLdeibOxVJUP1u1m/FOL+fHrq2iVlMCf7jiL1+8+m2E92zsdXr2sxmHCwg01gqZwQ/w2QC56Ld9ygJy561i+5VvS27fkoTH9+P6gbsTFhW5AX7CsOG6JwxW8Pi+QG+JvKIZYnG/Ky9btOsSUuXm8v24PqclJPHBRBtdlpdEswfnGH0scljhMjKir51F2t2yW3rXUgYhMbbbtL+GJBet5a9UOWiclcM8Ffbj93F60bBaC/klt2kBx8anbk5Ph0KGAn8Z6VRkTI0Iy+DJEJx5zqr3FpUz/YAOvLttGnAgTzjuNe87vQ9uWzUL3IrV9dvVtDwFLHMZ4WM0pRxrV88iBE0+0O3SsnFkfbeKFjzdTVlHJdWel8cCFGXRJae50aCFhicMYD6s55YgXa0nR5Fh5BX9esoU/LtzIwZJyLh3UlYfGZNK7YyunQwspSxzGhEEkpytpaMCfCT9fRSV/W7mdJxdsYNehY5zfL5VHxmYysHuK06GFhSUOY0KsZhfZVbtWMWfNHOsiG4VUlfe+2sVjuXls2neEM9Pb8sR1QzinTwenQwsrSxzGhJgbpisx4aWqfJy/j5y5eazZUURGp9bMvGUYYwZ0DuniSgFJTq67c0OYWOIwJsTcMF1JUBw48URUiHuNrSo4SM7cdXy6cT/d27bgsWsGc+WZ3Yl3avCeAz3fLHEYE2KeW58k2rvchqjXWP6eYh7LXc/cr3fRoVUzfnPpAG46O52khPgQBOktjg1XFJFMEVlV7eeQiPy4xj4XiEhRtX1+41S8xgQqVibna0iwc2i51Y6DR3nkr6sZ88QiPs7fx08u7sdHk0bxw+/2jsmkAS4ZOS4i8cAOYLiqbq22/QLgYVW9NJjns5HjxmlumK7ESa6aQ6u+mkM9578DR8p45sN8Xl6yFQRuPbsn/zGqL+1bhXDwnot4ceT4RcDG6knDGC+L9S6yXu4gcLjUxwuLN/Pc4k2UlPm4elgPHry4H93btnA6NNdwS+K4HnitjvvOEZHVQCFVVx9fRy4sY0xjeK6DAFDqq+DVpduY/kE++4+UMe47XXh4bD/6doqSTgIh5HjiEJFmwGXAL2q5+3Ogp6oeFpHxwFtARh3PMwGYAJCenh6maI3T3LAOuGmYqzoINNBrrKJSefOLHTwxfz07Dh7lnNM68LNL+jMkrW2EA/UOx2scInI5cK+qjglg3y1Alqruq28/q3FEJ1e1m3tNhCcy9MJnparM/2Y3U3Lz2LDnMGd0T2HSuEy+27dj5MdiuIDXahw3UEczlYh0AXarqopINlW9wPZHMjjjHl5uN3dchCcydPscWks27icndx1fbDtI746teObGoVwysIujCyl5iaOJQ0RaAqOBu6ttmwigqjOAq4F7RMQHHAWuV6cvkbwkyqbL9mK7eci55TMNIA43dhD4akcRObl5LFq/ly5tmvOHq87g6mE9SIh3fiElL3E0cahqCdChxrYZ1X6fDkyPdFxRI8qmy3ZVu7lT3PKZuiWOAG3ed4Sp8/J458udpLRI5Jfj+3PrOb1onhib4zCayg1NVcYEJCRrT5iYsvvQMaa9v4HXlxfQLD6Oe0f1YcJ5fUhpkeh0aJ5micN4RiTbza33lrcVlZTz7Ecbmf3pZioqlZuGp3PfhX3plBwdCyk5zfFeVeFgvar8GjliNta5ukdQYz/TUNdGXHpsHS2r4E+fbmbGwo0Ul/q4fHA3fjo6k/QOLR2L6QS31Kfq4LVeVca4SlT23nLBiSmcyisqeX15AU+9v4E9xaVc1L8TD4/N5PSubZwO7d88VheqjyWOaBbt02WHiat7b7nlM3VJHJWVyv9+Wcjj89ezdX8JZ/Vqxx9vGkpWr/YRjSPWWOKIZlH+LTNcXNF7q75mDTc0Mzp8bKkqC9fvJWduHmt3HqJ/l2RevD2LUZmdYnLwXqRZ4jCu4ZaCtCt6b0VDs0aY2vRXbj3A5Ll5LNt8gPT2LZl2/RC+P6ibDd6LICuOG1dwW0Ha8WnRXVp8DkqI30PermKm5OaxYO1uOrZO4oGL+nL9Wek0S/DI4D2Xf6ZWHDee47aCtBtHPdfL5T12mqLgQAlPLFjPm1/soHVSAo+MzeSOEb1o2cxjpy+X1IVCwWN/eROtXF2Q9oJoaNqqYW9xKc98mM+cpVuJE2HCeadxz/l9aNvSowspeTyBV2eJw7iCKwrSwYjib/gh0abx3WAPHSvn+UWbeP7jzZT6Krk2K40HL8qgS4oN3nMLSxzGFVxRkA5GuL/he71ZoxF/h2PlFby8ZCt/XJjPtyXlXDqoKz8d3Y/TUluHIUDTFJY4jCu4fRruiIvmq5Yayc9XUcnfP9/Okws2sLPoGCMzOjJpbH/O6JHiUICmIZY4jGt4riBtGsefFFWVuV/tYsq8PDbtPcKQtLZMvXYw5/bpGJrXsebEsKk3cYhIGyBVVTfW2D5IVb8Ma2TGmMB5rGnrk/x9TJ67ji+3F9G3U2tm3jKMMQM6h3bwXhR2GHCLOhOHiFwLPAnsEZFE4HZVXe6/ezYwNPzhGWMC4pFv0Ku7ZDDl+aV8nL+P7m1bMOXqQVw1tAfxNnjPU+q74vglMExVd/qXbX1ZRH6pqv8A7FM2sc1j3/AjrsbfJ799D6aedwvvZY6g/c5D/PrSAdw0PN0WUvKo+hJHvKruBFDVZSIyCnhHRHoAIRvmKCJbgGKgAvDVHLkoVdeu04DxQAlVVz6fh+r1jWkUj3zDd4z/71N48CjTFmzgrysLaJEYzwMjT+Oukb1Jbt7IhZQiUbew2kiD6kscxSLS53h9w3/lcQHwFvCdEMcxSlX31XHfJUCG/2c48Kz/X2OMS317pIw/LsznpSVbQeH2c3tz76g+dGidVLVDY0/OkahbWG2kQfUljnuAOBEZoKrfAKhqsYiMA66PSHRVLgf+rFWTan0mIm1FpOvxqyFjjHscKfXx4sebmbVoE0fKfFx5Zg9+MjqDHu1qLKQUiZOzNSeGTZ2JQ1VXA4jIVyLyMpADNPf/mwW8HKIYFJgnIgrMVNVZNe7vDhRUu73dv+2kxCEiE4AJAOnp6SEKzZgmiKEmjzJfJa8t28bTH2xg3+EyxgzozMNjM+nX2cGTdJT9jd0kkHEcw4HJwKdAMjAHGBHCGEaoaqGIdALmi8g6VV1U7f7aCvGn1Fj8CWcWVM2OG8L4jJO8fPKNgSaPikrln6t28Pj89Wz/9ihnn9aeWbf2Z2h6O6dDM2EUSOIoB44CLai64tisqpWhCkBVC/3/7hGRN4FsoHri2A5UHz7cAygM1esbl4uBk68XqSrvr93DlNw88nYX851ubfj9lWdwXkZHW0gpBgQykf1yqhLHWcB3gRtE5G+heHERaSUiycd/B8YAX9XY7W3gVqlyNlBk9Q1jnLN0036unrGEH/15BWUVlUy/8Uz+977vcn6/1PAnjbrqE6GsW0TiNTwukCuOO1X1+KpIu4DLReSWEL1+Z+BN/8GWALyqqnNFZCKAqs4A3qWqK24+Vd1x7wjRaxtTxcvNYRH0dWERU3LzWJi3l85tkvj9lQO5NiuNxPhGLKTU2MJ1JD4P+8wbZCsAGneLxKpp4XoNl6/4Fqit+48wdd563l5dSEqLRP7jgj7cdm4vG7wXZWwFQGPcwOPdQfccOsZTH2zgL8sKSIgX7h3Vhwnn9SGlRSMH75moYYnDuJuXT74ebfIoOlrOzI828uInm/FVKDdkp3P/hX3p1MYWUjJVLHEYd/PoydeLdZOjZRXM/nQLMz7ayKFj5Vw+uBs/Gd2Pnh1aOR2acRlLHMaEg4e6EZdXVPLGigKmLdjAnuJSRmWm8sjY/gzo1vjlX010s8RhTIyqrFTeWbOTx+flsWV/CVk92zH9xqFk927vdGjG5SxxGBNjVJWP1u8lZ24e3+w8RP8uybxwWxYX9u9kg/dMQCxxGBNDVm79lpy561i6+QBp7Vvw5HVD+P7gbraQkgmKJQ5jolGN4vz6julMGXkL8/udQ8fWzfjvy77DDdnpNEtoxOA9E/MscRgTDk53I/a/9vY2qTzx3Zv4x8ALaV12lIcWvcwPP3yFVkn2X980nh09xoTqJO+iLrj7WqbwzDnXMmfIeEC5a9mb3PPZ32h3rBiS/hLRWEz0scRhTKhO6i7oglt8rJznF2/m+QnPcTQxiWvWLODBT16jW3FdC2w6wEUJ9gQ3xuRiljiMiQLHyit45bOtPPNhPt+WlHPJli94aNHL9D2w3enQTuWCBBvwa7tw3I0bWOIwxsN8FZX844sdPDl/PYVFxxiZ0ZFHxmYyKO1Sp0MzUcwShzFOa0QziaqS+/UuHpu3nvw9hxncI4Up1wxmRN+O/36sV+f4Mq5nicMYpwXZTPJp/j4m5+axuuAgfVJb8exNQxk3sMvJg/esXd6EkSUOUzsrFgYvHN/yqyWDNZ37kHPRnSxOG0S3lObk/GAQVw3tTkJjFlJqCjs2Yp5jiUNE0oA/A12ASmCWqk6rsc8FwD+Bzf5N/1DVRyMZZ8yyYmHwwnTS3Ni+O4+PvJl/9R9Ju5Ii/vN7p3Pz2T2dW0ipqceGG5vR3BiTizl5xeEDHlLVz/3rjq8Ukfmq+k2N/RarqlX6TMzZmdyBp869gTcGjSbJV8YDn7zKXcveJPmpkvC/eH1XFU3lxqsSN8bkYo4lDlXdCez0/14sImuB7kDNxGFMTPm2eTIzzr6a2UMvpTIujls+/xf3LXmdjiVFkQvCrjhNPVxR4xCRXsCZwNJa7j5HRFYDhcDDqvp1BEMzJvz8zSQliUm8mHU5M7Ov4nBSS6766gN+/PGrpB3a43SExpzE8cQhIq2BvwM/VtWa14ufAz1V9bCIjAfeAjLqeJ4JwASA9PT0MEZsTGiVHTjIX5Zv46n389l3uJTRAzrz8ENXk7lvq9OhGVMrUVXnXlwkEXgHyFXVxwPYfwuQpar1zp+QlZWlK1asCE2Qscp6zoRdZaXy9upCps7Po+DAUbJ7t+dn4/ozrGc75//+9a3LUV8huamxOf2+Y5iIrFTVrED2dbJXlQAvAGvrShoi0gXYraoqItlAHLA/gmHGLvtPGjaqygfr9jAlN491u4oZ0LUNs+8YyPn9Uv89FsPNf/9wxma1FU9wsqlqBHALsEZEVvm3/RJIB1DVGcDVwD0i4gOOAterk5dIxjTR8i0HmPzeOlZs/ZaeHVry1A1ncukZXYmL9EJKDX2zt+6pph5O9qr6GKj3f4uqTgemRyYiY8Jn7c5DTMnN44N1e0hNTuJ/rhjIdWelkRjpwXvHNfTN3s1XPMZxjhfHjYlm2/aX8Pj8PP65upDkpAQmjcvk9nN70bKZ/dcz3mVHr4k+Liiw7ik+xtPv5/Pasm0kxAsTz+/DxPP6kNIyMSKvb0w4WeIw0cfBAmvR0XJmLdrIix9vobyikmvPSuPBizLo3KZ52F/bUaFK1lZb8QRLHMaEwLHyCl76dAt/XLiRoqPlXDa4Gz8d3Y9eHVs5HVpkhCpZW23FEyxxGNMEvopK/rpyO9MWbGDXoWNckJnKw2MyGdg9xenQ6mff7E0TWOIwpj51NMFUJrfhvY/XMXVeHpv2HWFoeluevH4IZ5/WwYEgG8G+2ZsmsMRhTH1qJA0FFvc6kynn3cqaVz+nX+fWPHdrFhef3unkhZSMiWKWOEz0CVMzzBdd+5Fz/m0s6TmYHgd3MfWawVxxZnfiIz14zxiHWeIw0SfEzTD5HXowZeSt5GaeS4cjB/ntgpncuOo9kmaUh/R1AuaC7sa1vrbVTGKGJQ5j6rDj4FGevORB/j7wQlqWl/LTxa/wwxX/pHXZUWcDc+N8TlYziSmWOIypYf/hUp75cCOvfLYVBpzPnSv+yT2f/Y32R+3kaAxY4jDmhMOlPp5fvInnFm3iaHkF1wxL48EHLqPbzlrWxbAmGBPDLHGYmFfqq2DOZ9uY/mE+B46UccnALjw0JpO+nVrD1VucDi+6uLE+Y4JmicN4QxhOOBWVyj8+386TCzaw4+BRRvTtwKSx/Rmc1raJwQYgVk+gbqzPmKBZ4jDeEMITjqoy75vdPJabx4Y9hxnUI4XJPxjEdzM6NjHIIDTl/VgPJuMwSxwmpizZuJ/Jc9exquAgp6W24tmbhjJuYBdvDd6L5isS4wmWOMzJorQJ5asdReTk5rFo/V66pjRn8g/O4AdDe5Dg1EJKxniYo4lDRMYB04B44HlV/UON+5OAPwPDqFpr/DpV3RLpOGNKlLVBb9p7mKnz1/OvL3fStmUivxp/Orec05PmifFOhxa8KE3qxnscSxwiEg88A4wGtgPLReRtVf2m2m5Bp2iGAAAOA0lEQVR3At+qal8RuR6YDFwX+WhNyETo5Ler6BjT3t/AGysKaBYfx/0X9uWu806jTXMPL6QUDUnd6jNRwckrjmwgX1U3AYjIX4DLgeqJ43Lgv/y//w2YLiKiqhrJQE0INfbkF+AJ52BJGc9+tJHZn2yhUpWbh6dz34UZpCYnNTLgMInVE6hdGUUFJxNHd6Cg2u3twPC69lFVn4gUAR2AfRGJ0LhHAyeckjIff/pkCzM+2sjhUh9XDOnOT0f3I619ywgFGCQ7gRoPczJx1NaNpeaVRCD7VO0oMgGYAJCent60yIxnlPkqeX35Nqa9n8++w6VcfHpnHh7bj/5d2jgdmjFRy8nEsR1Iq3a7B1BYxz7bRSQBSAEO1PZkqjoLmAWQlZVlTVmN5ZEmlMpK5X+/LGTqvPVsO1BCdq/2zLxlKMN6tnc6NGOinpOJYzmQISK9gR3A9cCNNfZ5G7gNWAJcDXxg9Y0wc3kTiqqyMG8vObl5rN15iP5dkvnT7WdxQWaqt8ZiNIZHkrqJfo4lDn/N4j4gl6ruuC+q6tci8iiwQlXfBl4AXhaRfKquNK53Kl7TRHX1pjougJPfii0HyJmbx7ItB0hv35Jp1w/h+4O6ERcrCym5PKmb2CHR+AU+KytLV6xY4XQYprr6rgYaOAbX7TrEY7l5LFi7h9TkJB64sC/XnZVOs4QYG7xn4zhMGInISlXNCmRfGzluXKvgQAlPzF/Pm6t20DopgUfGZnLHiF60bBajh200jOMwUSFG/wcaN9tbXMr0Dzbw6rJtxIlw93l9mHj+abRt2czp0IwxWOIwLnLoWDnPLdrECx9vptRXyXVnpfHAhRl0SWnudGjGmGoscRjHHSuv4OUlW3lmYT4HS8q5dFBXHhqTSe+OrZwOzRhTC0scJjJq6Urqkzj+dtalTHtsITuLjnFev1Qmjc1kYPcUh4I0xgTCEoeJjGq9flSV977axWPz8ti09whnpjTn8WuHcE6fDg4G6AE2jsO4hCUOE1Efb9hHTu46vtxeREan1sy6ZRijB3SO/sF7oWBdbo1LWOIwEbG64CA5uev4JH8/3du24LFrBnPlmd2Jd8vgPRsjYUzALHGYsMrfU8xjueuZ+/Uu2rdqxm8uHcBNZ6eTlOCyhZRsjIQxAbPEAfZtMwx2HDzKtAXr+dvK7bRIjOcnF/fjzpG9aZ0UY4ecHVsmCsXY/+I62LfNkDlwpIxnPszn5c+2gsLt5/bm3lF96NDaZQspVdcmjFOw27FlopAlDhMSh0t9vLB4M88t3kRJmY8fDO3Bgxdn0KOdSxdSqs5O4sYExRKHaZJSXwWvLt3G9A/y2X+kjDEDOvPI2EwyOlsXUWOilSUO0ygVlcpbX+zg8fnr2XHwKGef1p7nx/XnzPR2TocWWjZGwphTWOIwQVFVFqzdw5TcdazffZiB3dvw/686g5EZHaN3LEZt78uK2yaGWeIAG5EboKWb9jN57jo+33aQ3h1bMf3GMxk/sGt0L6TU1OK2HVsmClniAPvm2ICvC4uYkpvHwry9dG6TxP+78gyuyepBYnyULKRU38m9qYVzO7ZMFHIkcYjIFOD7QBmwEbhDVQ/Wst8WoBioAHyBrk5lQmPLviM8Pn89b68uJKVFIr+4pD+3nduL5okODN4L53iI+h4frc1vxjSBU1cc84Ff+Ncdnwz8AvhZHfuOUtV9kQvN7D50jKfe38DrywtIjI/jvlF9ueu800hpkehcUDYewhjXcCRxqOq8ajc/A652Ig5zsqKScmYs2sifPtmMr0K5cXg6913Yl07JtpCSMebf3FDj+CHweh33KTBPRBSYqaqzIhdW7DhaVsHsT7fw7MJ8ikt9XD64Gz8dnUl6Bw8M3gs3K24bc4qwJQ4RWQB0qeWuX6nqP/37/ArwAXPqeJoRqlooIp2A+SKyTlUX1fF6E4AJAOnp6U2OPxaUV1Ty+vICnnp/A3uKS7mofyceHpvJ6V3DOAWH11hx25hThC1xqOrF9d0vIrcBlwIXqarW8RyF/n/3iMibQDZQa+LwX43MAsjKyqr1+UyVykrlnTU7mTovj637S8jq2Y5nbhrKWb3aOx2aMcYDnOpVNY6qYvj5qlpSxz6tgDhVLfb/PgZ4NIJhRh1V5aP1e8mZm8c3Ow/Rv0syL96exajMTu4fvGdNRsa4hlM1julAElXNTwCfqepEEekGPK+q44HOwJv++xOAV1V1rkPxet7KrQeYPDePZZsPkN6+JdOuH8L3B3XzzuA9azIyxjWc6lXVt47thcB4/++bgMGRjCsa5e0qZkpuHgvW7qZj6yQevfw7XH9WOs0SomTwXl1sHQxjwsYNvapMGBQcKOGJBet584sdtG6WwCNjM7ljRC9aNouRj9zGfRgTNjFyFokde4tLeebDfOYs3UqcCHeNPI17zu9Du1bNnA7NGBMlLHFEieJj5Ty3aBPPf7yZUl8l12b14IGLMuia0sLp0IwxUcYSh8cdK6/glc+28syH+XxbUs74M7rw0JhM+qS2djo0Y0yUssThUb6KSv7x+Q6eXLCewqJjjMzoyCNjMxnUo63ToRljopwlDo9RVXK/3sWU3Dw27j3C4LS2PHbNYM7t29Hp0NzFxn0YEzaWODzk0/x9TM7NY3XBQfp2as2Mm4cy9jtd3D94zwnW5daYsLHE4QFfbj/IlNw8Fm/YR7eU5uRcPYirzuxOQrQspGSM8RRLHC62ce9hps7L4901u2jXMpH//N7p3Hx2T2cWUjLGGD9LHC60s+go0xZs4K8rt9M8IY4HL8rgRyN7k9zcwYWUjDHGzxKHi3x7pIw/LsznpSVbQeHWc3py76i+dGyd5HRoxhhzgiUOFzhS6uPFjzcza9EmjpT5uGpoD358cQY92tlCSsYY97HE4bBP8/fxwF++YN/hMsYM6MzDYzPp19m6jBpj3MsSh8N6p7ZiQLcUfnxxBkPT2zkdjjHGNMgSh8O6prTgzz/MdjoMY4wJmA0EMMYYExRLHMYYY4LiSOIQkf8SkR0issr/M76O/caJSJ6I5IvIzyMdpzHGmFM5WeN4QlUfq+tOEYkHngFGA9uB5SLytqp+E6kAjTHGnMrNTVXZQL6qblLVMuAvwOUOx2SMMTHPycRxn4h8KSIvikht/VC7AwXVbm/3b6uViEwQkRUismLv3r2hjtUYY4xf2BKHiCwQka9q+bkceBboAwwBdgJTa3uKWrZpXa+nqrNUNUtVs1JTU0PyHowxxpwqbDUOVb04kP1E5DngnVru2g6kVbvdAygMQWjGGGOawJHiuIh0VdWd/ptXAl/VsttyIENEegM7gOuBGwN5/pUrV+4Tka0hCTYyOgL7nA6iESzuyPFizGBxR1JTY+4Z6I5O9arKEZEhVDU9bQHuBhCRbsDzqjpeVX0ich+QC8QDL6rq14E8uap6qq1KRFaoapbTcQTL4o4cL8YMFnckRTJmRxKHqt5Sx/ZCYHy12+8C70YqLmOMMQ1zc3dcY4wxLmSJwx1mOR1AI1nckePFmMHijqSIxSyqdfZwNcYYY05hVxzGGGOCYonDJUTkd/6R9KtEZJ6/h5nricgUEVnnj/1NEWnrdEwNEZFrRORrEakUEdf3nPHiZJ/+GSH2iEhtXe1dSUTSRORDEVnrPz4edDqmQIhIcxFZJiKr/XH/d9hf05qq3EFE2qjqIf/vDwADVHWiw2E1SETGAB/4u09PBlDVnzkcVr1E5HSgEpgJPKyqKxwOqU7+yT7XU22yT+AGt0/2KSLnAYeBP6vqQKfjCYSIdAW6qurnIpIMrASu8MDfWoBWqnpYRBKBj4EHVfWzcL2mXXG4xPGk4deKeqZXcRNVnaeqPv/Nz6ga4e9qqrpWVfOcjiNAnpzsU1UXAQecjiMYqrpTVT/3/14MrKWe+fHcQqsc9t9M9P+E9fxhicNFROT3IlIA3AT8xul4GuGHwHtOBxFlgprs04SGiPQCzgSWOhtJYEQkXkRWAXuA+aoa1rgtcURQAxM/oqq/UtU0YA5wn7PR/ltDcfv3+RXgoyp2xwUSs0cENdmnaToRaQ38HfhxjZYA11LVClUdQtUVf7aIhLV50MmFnGJOoBM/Aq8C/wJ+G8ZwAtZQ3CJyG3ApcJG6pGgWxN/a7Wyyzwjy1wj+DsxR1X84HU+wVPWgiCwExlH7HIAhYVccLiEiGdVuXgascyqWYIjIOOBnwGWqWuJ0PFHoxGSfItKMqsk+33Y4pqjkLzK/AKxV1cedjidQIpJ6vDejiLQALibM5w/rVeUSIvJ3IJOq3j5bgYmqusPZqBomIvlAErDfv+kzt/cGE5ErgaeBVOAgsEpVxzobVd1EZDzwJP+e7PP3DofUIBF5DbiAqhlbdwO/VdUXHA2qASLyXWAxsIaq/4cAv/TPmedaIjIIeImq4yMOeENVHw3ra1riMMYYEwxrqjLGGBMUSxzGGGOCYonDGGNMUCxxGGOMCYolDmOMMUGxxGFMBInIXBE5KCLvOB2LMY1licOYyJoC3OJ0EMY0hSUOY8JARM7yr1HSXERa+ddJGKiq7wPFTsdnTFPYXFXGhIGqLheRt4H/AVoAr6iqZxY1MqY+ljiMCZ9HqZpr6hjwgMOxGBMy1lRlTPi0B1oDyUBzh2MxJmQscRgTPrOAX1O1Rslkh2MxJmSsqcqYMBCRWwGfqr7qXzf8UxG5EPhvoD/QWkS2A3eqaq6TsRoTLJsd1xhjTFCsqcoYY0xQLHEYY4wJiiUOY4wxQbHEYYwxJiiWOIwxxgTFEocxxpigWOIwxhgTFEscxhhjgvJ/jPR2lVukWYcAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1f7a0c01f98>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotBestFit(weights, dataList, labelList)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stocGradAscent1(dataList, labelList, MaxIter=150):\n",
    "    '''\n",
    "    随机梯度上升(控制整个迭代次数以足够达到收敛，每次随机选取样本)\n",
    "    Args:\n",
    "        dataMatrix: 训练集特征 \n",
    "        classLabels：训练集分类标记\n",
    "        alpha = 0.01：学习率\n",
    "    Return:\n",
    "        weights: 更新后的回归系数\n",
    "    '''\n",
    "    dataMatrix = np.mat(dataList)\n",
    "    classLabels = np.mat(labelList).T\n",
    "    m,n = np.shape(dataMatrix)\n",
    "    weights = np.ones((n,1))\n",
    "    for j in range(MaxIter):\n",
    "        dataIndex = range(m)\n",
    "        for i in range(m):\n",
    "            # 每次迭代体征学习率\n",
    "            alpha = 4 / (1.0 + j + i) + 0.01\n",
    "            randIndex = int(np.random.uniform(0, len(dataIndex)))\n",
    "            h = sigmoid(np.sum(dataMatrix[randIndex]*weights))\n",
    "            error = classLabels[randIndex] - h\n",
    "            weights = weights + dataMatrix[randIndex].T * alpha * error \n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[13.64987666],\n",
       "        [ 1.05845884],\n",
       "        [-1.81470255]])"
      ]
     },
     "execution_count": 186,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataList, labelList = loadDataSet('data/testSet.txt')\n",
    "weights = stocGradAscent1(dataList, labelList)\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1f7a0e2b7f0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotBestFit(weights, dataList, labelList)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 小例子：从疝气病症预测病马的死亡率\n",
    "### 1.处理数据中的缺失值\n",
    "可选做法：<br/>\n",
    "（1）使用可用特征的均值太填补缺失值<br/>\n",
    "（2）使用特殊值来填补缺失值，如-1<br/>\n",
    "（3）忽略有缺失值的样本<br/>\n",
    "（4）使用相似样本的均值来添补缺失值<br/>\n",
    "（5）使用另外的机器学习算法预测缺失值<br/>\n",
    "**在此，我们选择第（2）种方法，对缺失值替换成0，这是由于当特征值为0时，对应系数将不做更新；且sigmiod(0)=0.5，对结果的预测不具有倾向性。若类别标签缺失，则丢弃数据**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [],
   "source": [
    " def classifyVector(inx, weights):\n",
    "        '''\n",
    "        分类函数\n",
    "        Args:\n",
    "            inx: 每个样本特征向量\n",
    "            weights: 逻辑回归系数参数\n",
    "        Return:\n",
    "            分类标签1或0\n",
    "        '''\n",
    "        prob = sigmoid(np.sum(inx * weights))\n",
    "        if prob > 0.5:\n",
    "            return 1.0\n",
    "        else:\n",
    "            return 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [],
   "source": [
    "def colicTest():\n",
    "    '''\n",
    "    测试函数\n",
    "    使用训练集训练模型，再使用测试集进行测试，并计算出错误率\n",
    "    '''\n",
    "    trainFile = 'data/horseColicTraining.txt'\n",
    "    testFile = 'data/horseColicTest.txt'\n",
    "    trainingSet = []\n",
    "    trainingLabels = []\n",
    "    # 训练出模型参数\n",
    "    with open(trainFile) as ftrain:\n",
    "        for line in ftrain:\n",
    "            lineArr = line.strip().split('\\t')\n",
    "            lineArr = list(map(float, lineArr))\n",
    "            trainingSet.append(lineArr[:-1])\n",
    "            trainingLabels.append(lineArr[-1])\n",
    "    trainWeights = stocGradAscent1(trainingSet, trainingLabels, 500)\n",
    "    # 使用训练好的模型进行验证\n",
    "    errorCount = 0\n",
    "    numTestVec = 0.0\n",
    "    with open(testFile) as ftest:\n",
    "        for line in ftest:\n",
    "            numTestVec += 1.0\n",
    "            lineArr = line.strip().split('\\t')\n",
    "            lineArr = list(map(float, lineArr))\n",
    "            testArr = lineArr[:-1]\n",
    "            testLabel = lineArr[-1]\n",
    "            if int(classifyVector(testArr, trainWeights)) != int(testLabel):\n",
    "                errorCount += 1\n",
    "    errorRate = (float(errorCount)/numTestVec)\n",
    "    print('the error rate of this test is: %f' % errorRate)\n",
    "    return errorRate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiTest():\n",
    "    '''\n",
    "    进行10次模型的训练与预测，并对10次的错误率求平均值\n",
    "    '''\n",
    "    numTests = 10\n",
    "    errorSum = 0.0\n",
    "    for k in range(numTests):\n",
    "        errorSum += colicTest()\n",
    "    print('after %d iterations the average error rate is : %f' % (numTests, errorSum/float(numTests)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda\\lib\\site-packages\\ipykernel_launcher.py:5: RuntimeWarning: overflow encountered in exp\n",
      "  \"\"\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the error rate of this test is: 0.507463\n",
      "the error rate of this test is: 0.313433\n",
      "the error rate of this test is: 0.253731\n",
      "the error rate of this test is: 0.462687\n",
      "the error rate of this test is: 0.328358\n",
      "the error rate of this test is: 0.313433\n",
      "the error rate of this test is: 0.388060\n",
      "the error rate of this test is: 0.328358\n",
      "the error rate of this test is: 0.567164\n",
      "the error rate of this test is: 0.388060\n",
      "after 10 iterations the average error rate is : 0.385075\n"
     ]
    }
   ],
   "source": [
    "multiTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
